/*
 * This file is part of "Deathwatch Ammo Counter for Android".
 *
 * "Deathwatch Ammo Counter for Android" is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation, either version 3 of the License, 
 * or (at your option) any later version.
 *
 * "Deathwatch Ammo Counter for Android" is distributed in the hope that it 
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with "Deathwatch Ammo Counter for Android".  
 * If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package com.TikiiTorch.Deathwatch.AmmoCounter.activities;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.TikiiTorch.Deathwatch.AmmoCounter.AmmoLoad;
import com.TikiiTorch.Deathwatch.AmmoCounter.Ammunition;
import com.TikiiTorch.Deathwatch.AmmoCounter.R;
import com.TikiiTorch.Deathwatch.AmmoCounter.SpaceMarine;
import com.TikiiTorch.Deathwatch.AmmoCounter.Weapon;
import com.TikiiTorch.Deathwatch.AmmoCounter.file.FileManager;

public class DWAmmo extends Activity {

	TextView ammoName, inClip, inBag, clipsRemain;
	Button single, semi, auto, reload;
	Spinner weapSpinner;

	ListView ammoList;

	SpaceMarine marine;

	String selected;

	boolean updateFromWeapChange = false;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.weapon_view);

		Bundle extra = getIntent().getExtras();

		if (extra != null) {
			try {
				marine = FileManager.getSpaceMarine(extra
						.getString("character"));
			} catch (Exception e) {
				e.printStackTrace();
				finish();
			}
		} else {
			finish();
		}

		ammoList = (ListView) findViewById(R.id.ammoList);

		ammoName = (TextView) findViewById(R.id.ammoName);
		inClip = (TextView) findViewById(R.id.inClip);
		inBag = (TextView) findViewById(R.id.inBag);
		clipsRemain = (TextView) findViewById(R.id.clipsRemain);

		single = (Button) findViewById(R.id.btnfireSingle);
		semi = (Button) findViewById(R.id.btnfireSemi);
		auto = (Button) findViewById(R.id.btnfireAuto);

		reload = (Button) findViewById(R.id.btnreload);

		weapSpinner = (Spinner) findViewById(R.id.weapSpinner);
		weapSpinner.setOnItemSelectedListener(new WeaponSelectListener());

		FireShots shotListener = new FireShots();

		single.setOnClickListener(shotListener);
		semi.setOnClickListener(shotListener);
		auto.setOnClickListener(shotListener);

		reload.setOnClickListener(new Reload());
	}

	@Override
	public void onResume() {
		super.onResume();

		if (marine.weaponCount() <= 0) {
			forceAddWeapon();
		} else {
			update();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// handle item selection
		switch (item.getItemId()) {
		case (R.id.menu_reqAmmo):
			addAmmo();
			return true;
		case (R.id.menu_addWeap):
			addWeapon();
			return true;
		case (R.id.menu_delWeap):
			removeWeapon();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case (AmmoPicker.PICK_AMMO_REQUEST):
			if (resultCode == RESULT_OK) {
				Ammunition ammo = data.getParcelableExtra("selectedAmmo");
				AmmoLoad ammoSupply = new AmmoLoad(ammo, 280, marine
						.activeWeapon().getClipSize());
				marine.activeWeapon().addAmmoLoad(ammoSupply);
				update();
			}
			break;
		case (WeaponPicker.PICK_WEAPON_REQUEST):
			if (resultCode == RESULT_OK) {
				Weapon weapon = data.getParcelableExtra("selectedWeapon");
				marine.addWeapon(weapon);
				marine.setActiveWeapon((marine.weaponList().length) - 1);
				update();
			}
			break;
		}
	}

	private void addAmmo() {
		Intent pickAmmoIntent = new Intent(this, AmmoPicker.class);

		pickAmmoIntent.putExtra("gunType", marine.activeWeapon().getAmmoType());

		startActivityForResult(pickAmmoIntent, AmmoPicker.PICK_AMMO_REQUEST);
	}

	private void forceAddWeapon() {
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		alert.setTitle("No Weapons");
		alert.setMessage("Please select your first weapon.");
		alert.setCancelable(false);
		alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				addWeapon();

			}
		});
		alert.show();
	}

	private void addWeapon() {
		Intent pickWeaponIntent = new Intent(this, WeaponPicker.class);

		startActivityForResult(pickWeaponIntent,
				WeaponPicker.PICK_WEAPON_REQUEST);
	}

	/**
	 * Asks the user if they want to remove the active weapon. If so, the weapon
	 * is removed.
	 */
	private void removeWeapon() {

		AlertDialog.Builder delWeapAlert = new AlertDialog.Builder(this);
		delWeapAlert.setTitle(marine.activeWeapon().getName());
		delWeapAlert.setMessage("Are you sure you want to remove this weapon?");
		delWeapAlert.setPositiveButton("Remove",
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						marine.removeWeapon(marine.getActiveWeapon());
						marine.setActiveWeapon(0);
						Toast.makeText(getApplicationContext(),
								"Weapon Removed", Toast.LENGTH_SHORT).show();
						update();

					}
				});
		delWeapAlert.setNegativeButton("Cancel", null);

		delWeapAlert.show();

	}

	private void update() {

		if (marine.weaponCount() <= 0) {
			forceAddWeapon();
			return;
		}

		AmmoLoad loadedSupply = null;

		if (marine.activeWeapon().getLoadedAmmo() >= 0) {
			loadedSupply = marine.activeWeapon().getAmmoLoads()
					.get(marine.activeWeapon().getLoadedAmmo());
		}

		if (!updateFromWeapChange) {
			ArrayAdapter<String> weapAdapter = new ArrayAdapter<String>(this,
					android.R.layout.simple_spinner_item, marine.weaponList());
			weapAdapter
					.setDropDownViewResource(R.layout.weap_list_dropdown_item);
			weapSpinner.setAdapter(weapAdapter);
			if (marine.getActiveWeapon() != weapSpinner
					.getSelectedItemPosition()) {
				weapSpinner.setSelection(marine.getActiveWeapon(), true);
			}
		}

		int[] rof = marine.activeWeapon().getROF();

		if (loadedSupply != null) {

			ammoName.setText(loadedSupply.getName());
			inClip.setText(String.format("%03d", loadedSupply.getClipAmount()));
			clipsRemain.setText(String.valueOf(loadedSupply.getClipNum()));
			inBag.setText(String.valueOf(loadedSupply.getBagAmount()));

			// turn off buttons that are unavailable
			single.setEnabled((loadedSupply.getClipAmount() >= rof[0])
					&& (rof[0] > 0));
			semi.setEnabled((loadedSupply.getClipAmount() >= rof[1])
					&& (rof[1] > 0));
			auto.setEnabled((loadedSupply.getClipAmount() >= rof[2])
					&& (rof[2] > 0));
			reload.setEnabled(loadedSupply.getBagAmount() > 0);
		} else {
			ammoName.setText("Empty");
			inClip.setText(String.format("%03d", 0));
			clipsRemain.setText(String.valueOf(0));
			inBag.setText(String.valueOf(0));

			single.setEnabled(false);
			semi.setEnabled(false);
			auto.setEnabled(false);
			reload.setEnabled(false);
		}

		// refresh the ammo list

		ArrayAdapter<AmmoLoad> loadAdapter = new AmmoLoadAdapter(this,
				R.layout.ammo_view, marine.activeWeapon().getAmmoLoads());
		ammoList.setAdapter(loadAdapter);

		FileManager.saveSpaceMarineFile(this, marine);

	}

	private class AmmoLoadAdapter extends ArrayAdapter<AmmoLoad> {

		private ArrayList<AmmoLoad> items;

		public AmmoLoadAdapter(Context context, int textViewResourceId,
				ArrayList<AmmoLoad> items) {
			super(context, textViewResourceId, items);
			this.items = items;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			View v = convertView;

			final int index = position;

			if (v == null) {
				LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				v = vi.inflate(R.layout.ammo_view, null);
			}

			AmmoLoad load = items.get(position);

			if (load != null) {

				TextView name = (TextView) v.findViewById(R.id.ammoViewName);
				TextView clipsRemain = (TextView) v
						.findViewById(R.id.ammoView_clipsRemain);
				TextView totalRounds = (TextView) v
						.findViewById(R.id.ammoView_totalRounds);

				Button btnLoad = (Button) v.findViewById(R.id.activateButton);

				ImageView imgInfo = (ImageView) v.findViewById(R.id.imgInfo);
				ImageView imgDelete = (ImageView) v
						.findViewById(R.id.imgDelete);

				if (name != null) {
					name.setText(load.getName());
				}

				if (clipsRemain != null) {
					clipsRemain.setText(String.valueOf(load.getClipNum()));
				}

				if (totalRounds != null) {
					totalRounds
							.setText(String.valueOf(load.getCurrentAmount()));
				}

				btnLoad.setOnClickListener(new View.OnClickListener() {

					@Override
					public void onClick(View v) {
						marine.activeWeapon().setLoadedAmmo(index);
						update();
					}
				});

				imgInfo.setOnClickListener(new AmmoInfoListener(position));
				imgDelete.setOnClickListener(new AmmoDeleteListener(position));

			}
			return v;
		}
	}

	private class FireShots implements View.OnClickListener {

		@Override
		public void onClick(View v) {

			int shotType = -1;

			switch (v.getId()) {
			case R.id.btnfireSingle:
				shotType = Weapon.RATE_OF_FIRE_SINGLE;
				break;
			case R.id.btnfireSemi:
				shotType = Weapon.RATE_OF_FIRE_SEMI;
				break;
			case R.id.btnfireAuto:
				shotType = Weapon.RATE_OF_FIRE_FULL;
				break;
			default:
				break;
			}

			if (shotType >= 0) {
				marine.activeWeapon().fire(
						marine.activeWeapon().getROF(shotType));
				update();
			}
		}

	}

	private class Reload implements View.OnClickListener {

		@Override
		public void onClick(View v) {
			marine.activeWeapon().reload();
			update();
		}

	}

	private class AmmoInfoListener implements View.OnClickListener {

		private int position;

		public AmmoInfoListener(int position) {
			this.position = position;
		}

		@Override
		public void onClick(View v) {

			AlertDialog.Builder effectAlert = new AlertDialog.Builder(
					v.getContext());

			String name = marine.activeWeapon().getAmmoLoads().get(position)
					.getName();

			String effect = marine.activeWeapon().getAmmoLoads().get(position)
					.getEffect();

			effect = (effect.equalsIgnoreCase("none")) ? "No special effect."
					: effect;

			effectAlert.setTitle(name);

			effectAlert.setMessage(effect);

			effectAlert.setPositiveButton("Close", null);

			effectAlert.show();

		}
	}

	private class AmmoDeleteListener implements View.OnClickListener {

		private int position;

		public AmmoDeleteListener(int position) {
			this.position = position;
		}

		@Override
		public void onClick(View v) {

			AlertDialog.Builder deleteAlert = new AlertDialog.Builder(
					v.getContext());

			String name = marine.activeWeapon().getAmmoLoads().get(position)
					.getName();

			deleteAlert.setTitle(name);

			deleteAlert
					.setMessage("Are you sure you want to remove this supply of "
							+ name + "?");

			deleteAlert.setPositiveButton("Remove",
					new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							marine.activeWeapon().removeammoLoad(position);
							update();
						}
					});

			deleteAlert.setNegativeButton("Cancel", null);

			deleteAlert.show();

		}

	}

	private class WeaponSelectListener implements OnItemSelectedListener {

		@Override
		public void onItemSelected(AdapterView<?> parent, View view, int pos,
				long id) {
			marine.setActiveWeapon(pos);
			updateFromWeapChange = true;
			update();
			updateFromWeapChange = false;
		}

		@Override
		public void onNothingSelected(AdapterView<?> arg0) {
			// Do nothing
		}

	}

}